import { log } from "cc";


import { EDITOR, EDITOR_NOT_IN_PREVIEW } from "cc/env";


/**
 * 埋点上报
 */

import crypto from 'crypto-es';


import { BattleMode } from "sgc";
import { TrackingLoadEvent, TrackingLoading } from "./loading";
import { TrackingGame, TrackingGameEvent } from "./game";
import { TrackingNetwork, TrackingNetworkEvent } from "./network";
import { TrackingSuileyoo, TrackingSuileyooEvent } from "./suileyoo";
import { TrackingSystem, TrackingSystemEvent } from "./system";

import { GlobalEventConstant, Manager } from "@shimotsuki/core";
import { BaseManager } from "@shimotsuki/core";
import { BaseAPI } from "../api/BaseAPI";





/**事件 */
type TrackingEvent = TrackingLoadEvent | TrackingGameEvent | TrackingSystemEvent | TrackingNetworkEvent | TrackingSuileyooEvent


// /**事件类型 */
// export enum TrackingEventType {
//     /**游戏加载 */
//     LOAD_EVENT = 'load_event',
//     /**游戏事件 */
//     GAME_EVENT = 'game_event',
//     /**系统事件 */
//     SYSTEM_EVENT = 'system_event',
//     /**网络事件 */
//     NETWORK_EVENT = 'network_event',
//     /**时长统计心跳事件 */
//     DURATION_EVENT = 'duration_event',
// }



/**基础字段 */
type Base = {
    /**用户ID */
    uid: string
    /**游戏 */
    gamename: string
    /**渠道名称 */
    channel_name: string
    /**(新表)对战模式 */
    battle_mode: BattleMode,
    /**队伍数量 */
    team_num?: number,
    /**每队人数 */
    perteam_num?: number,
    /**队伍id */
    team_id?: string,
    /**对局id */
    battle_id: string,
    /**房间id */
    room_id: string
    /**自定义事件名 */
    event_type: TrackingEvent
    /**event_type对应信息(与evnet_type一对一直接扩展，整个json需要urlencode 编码) */
    event_properties: string
}


// type Options<T extends TrackingEventType> = {
//     event_name: T extends TrackingEventType.LOAD_EVENT ? TrackingLoadEvent :
//     T extends TrackingEventType.GAME_EVENT ? TrackingGameEvent :
//     T extends TrackingEventType.SYSTEM_EVENT ? TrackingSystemEvent :
//     T extends TrackingEventType.NETWORK_EVENT ? TrackingNetworkEvent :
//     never;
//     value?: any;
// }

type Data = {
    /**表名 */
    mq: string;
    /**数据 */
    data: string;
}

type Jsdata = {
    para: Data[];
    type: 'object';
}

// 扩展 Manager 接口，添加 Platform 属性
declare module '@shimotsuki/core' {
    interface Manager {
        tracking: Tracking;
    }
}



/**
 * 埋点统计
 */
export class Tracking extends BaseAPI {

    game: TrackingGame
    loading: TrackingLoading
    network: TrackingNetwork
    suileyoo: TrackingSuileyoo
    system: TrackingSystem

    constructor(cat: Manager) {
        super(cat);
        this.init()

        this.game = new TrackingGame(this)
        this.loading = new TrackingLoading(this)
        this.network = new TrackingNetwork(this)
        this.suileyoo = new TrackingSuileyoo(this)
        this.system = new TrackingSystem(this)
    }


    private ecbkey: crypto.lib.WordArray
    private ecbiv: crypto.lib.WordArray


    init() {
        this.cat.event.on(GlobalEventConstant.EVENT_SHOW, this.onShowHandler, this)
        this.cat.event.on(GlobalEventConstant.EVENT_HIDE, this.onHideHandler, this)

        this.ecbkey = crypto.enc.Utf8.parse(this.cat.env.event_tracking_key); //十六位十六进制数作为秘钥
        this.ecbiv = crypto.enc.Utf8.parse(this.cat.env.event_tracking_key);  //十六位十六进制数作为秘钥偏移量
        // 添加心跳
        // timer.registerInterval(this, 1000 * 30, () => {
        //     this.onHeartBeatHandler()
        // })
    }

    private onShowHandler() {
        // api.tracking('SWITCH_FRONTEND')
        // log('SWITCH_FRONTEND')
    }
    private onHideHandler() {
        // api.tracking('SWITCH_BACKEND')
        // log('SWITCH_BACKEND')
    }

    private onHeartBeatHandler() {
        // api.tracking('HEART_BEAT')
        // upload({
        //     event_type: TrackingDurationEvent.DURATION_CHECK,
        //     data: {
        //         event_name: TrackingDurationEvent.DURATION_CHECK
        //     }
        // })
    }


    /**数据上报接口字段处理 */
    sign = (data: Base): Jsdata => {
        let jsdata: Jsdata = { type: 'object', para: [] };
        let paraArr = [];
        const is_test = this.cat.env.event_tracking_key
        paraArr.push({ mq: 'social_games', data: is_test ? [data] : this.encodeECB(`[${JSON.stringify(data)}]`) });
        // @ts-ignore
        jsdata.para = paraArr;
        return jsdata;
    };

    encodeECB = (message: string) => {
        let srcs = crypto.enc.Utf8.parse(message);
        let encrypted = crypto.AES.encrypt(srcs, this.ecbkey, { iv: this.ecbiv, mode: crypto.mode.ECB, padding: crypto.pad.ZeroPadding });
        let hexStr = crypto.enc.Hex.parse((encrypted.ciphertext || new crypto.lib.WordArray()).toString().toUpperCase());
        let baseSrcs = crypto.enc.Base64.stringify(hexStr);
        return baseSrcs;
    };



    /**http */
    protected http = async (opts: Base) => {
        let param = this.sign(opts);

        this.api({
            url: this.cat.env.event_tracking_url,
            method: 'POST',
            data: JSON.stringify(param),
            headers: {
                'Content-Type': 'application/json; charset=utf-8'
            }
        })
    };


    /**数据上报接口 */
    upload = <T extends TrackingEvent>({ event_type, value }: { event_type: T; value?: any }) => {

        // TODO 自定义上报内容

        // const { userTeamId } = this.cat.store.user
        // const { battle } = this.cat.store.game
        // const { mode, battleId } = this.cat.store.user.auth

        // const { token } = this.cat.store.user.auth

        // const base: Base = {
        //     uid: `${room_token ?? ''}`,
        //     event_type,
        //     event_properties: JSON.stringify(value),
        //     gamename: '',
        //     channel_name: '',
        //     battle_mode: mode ?? 0,
        //     battle_id: id ?? '',
        //     room_id: store.lobby.matchRoom.ddRid ?? '',

        // };

        // const nonce = {
        //     ...base,
        //     ...(battle.mode != BattleMode.UNSPECIFIED ? { team_num: battle.teams, perteam_num: battle.teamPlayers } : {}),
        //     ...(userTeamId ? { team_id: userTeamId } : {}),

        // }
        // TODO 关闭上报
        // this.http(nonce);

    };
}

